// Morse Code Playback Functions
// Formerly Mark Jessop 2018-04 & OK1TE 2018-11, who did this totally differently.
// (no longer) Based on code from https://github.com/Paradoxis/Arduino-morse-code-translator/blob/master/main.ino
// --
// Who on earth does string constants in embedded code..
// Chris Baird,, <chris.j.baird@gmail.com> 2020-03-26

#include "morse.h"
#include "config.h"
#include "radio.h"
#include "delay.h"

#define GREEN  GPIO_Pin_7
#define RED    GPIO_Pin_8

int MORSE_DELAY = (1200 / MORSE_WPM);
#define MORSE_DELAY_DIT (MORSE_DELAY * 1)
#define MORSE_DELAY_DAH (MORSE_DELAY * 3)


/* Idea from 'Efficient Storage Of Morse Code Character Codes',
 * Lawrence Krakauer, page 36, Issue 14, BYTE 1976-10
 */

const unsigned char morsetable[] =
  {
    'A', 0b01100000, 'B', 0b10001000, 'C', 0b10101000, 'D', 0b10010000,
    'E', 0b01000000, 'F', 0b00101000, 'G', 0b11010000, 'H', 0b00001000,
    'I', 0b00100000, 'J', 0b01111000, 'K', 0b10110000, 'L', 0b01001000,
    'M', 0b11100000, 'N', 0b10100000, 'O', 0b11110000, 'P', 0b01101000,
    'Q', 0b11011000, 'R', 0b01010000, 'S', 0b00010000, 'T', 0b11000000,
    'U', 0b00110000, 'V', 0b00011000, 'W', 0b01110000, 'X', 0b10011000,
    'Y', 0b10111000, 'Z', 0b11001000, '0', 0b11111100, '1', 0b01111100,
    '2', 0b00111100, '3', 0b00011100, '4', 0b00001100, '5', 0b00000100,
    '6', 0b10000100, '7', 0b11000100, '8', 0b11100100, '9', 0b11110100,
    '(', 0b10110100, ')', 0b10110110, ',', 0b11001110, '-', 0b10000110,
    '.', 0b01010110, '/', 0b10010100, ':', 0b11100010, ';', 0b10101010,
    '=', 0b10001100, '?', 0b00110010, '@', 0b01101010, '+', 0b01010100,
    '&', 0b01000100, '\"',0b01001010, '\'',0b01111010,
    0,0
  };


char morse_sanitize (char c)
{
  char r = 0;
  if ((c > 96) && (c < 123)) c -= 32;
  if ((c > 64) && (c < 91)) r = c;
  if ((c > 47) && (c < 58)) r = c;
  return r;
}


void encode_char_ook (unsigned char c)
{
  int i = 0;
  unsigned char j;

  c = morse_sanitize(c);

  for (i = 0; j = morsetable[i], j && (j != c); i += 2) continue;

  if (j)
    {
      unsigned char b = morsetable[i+1];
      do
        {
	  radio_enable_tx();
	  GPIO_ResetBits(GPIOB, RED); /* too lazy to include in led_enabled */
	  _delay_ms (b&128 ? MORSE_DELAY_DAH : MORSE_DELAY_DIT);
	  GPIO_SetBits(GPIOB, RED);
	  radio_disable_tx();
	  _delay_ms (MORSE_DELAY_DIT);
          b = (b & 127) << 1;
        }
      while (b != 128);

      _delay_ms (MORSE_DELAY_DIT*2);
    }
  else
    /* tx idle-dah on unknown/space characters */
    _delay_ms (MORSE_DELAY_DAH);
}


void send_morse (const char* message)
{
  radio_enable_tx ();
  while (*message) encode_char_ook (*message++);
  radio_disable_tx ();
}
